﻿// -------------------------------------------------------------------------
//    @FileName         :    NFCityLoginModule.cpp
//    @Author           :    Gao.Yi
//    @Date             :    2025-09-16
//    @Email			:    445267987@qq.com
//    @Module           :    NFCityLoginModule
//    @Desc             :
//
// -------------------------------------------------------------------------

#include "NFCityLoginModule.h"

#include "NFCityCheckTimer.h"
#include "NFCityPacketSendUtil.h"
#include "NFCityPlayer.h"
#include "NFCityPlayerUtil.h"
#include "NFCitySession.h"

NFCityLoginModule::NFCityLoginModule(NFIPluginManager* p) : NFCityDynamicModule(p)
{
}

NFCityLoginModule::~NFCityLoginModule()
{
}

int NFCityLoginModule::Awake()
{
    RegisterClientMessage(NF_ST_CITY_SERVER, E_CS_HEARTBEAT_REQ);
    RegisterClientMessage(NF_ST_CITY_SERVER, E_CS_BATTLESVR_RTT_REQ);
    RegisterClientMessage(NF_ST_CITY_SERVER, E_CS_MAPSVR_LOGIN_REQ);
    return 0;
}

int NFCityLoginModule::OnHandleClientMessage(NFDataPackage& packet, NFCitySession* pSession, const proto_ff::Proto_CSReq& req)
{
    int iRetCode = 0;
    if (!m_pObjPluginManager->IsInited(NF_ST_CITY_SERVER))
    {
        NFLogError(NF_LOG_DEFAULT, packet.nParam1, "City Server not inited, drop client msg:{}", packet.ToString());
        return -1;
    }

    if (m_pObjPluginManager->IsServerStopping())
    {
        NFLogError(NF_LOG_DEFAULT, packet.nParam1, "City Server is Stopping, drop client msg:{}", packet.ToString());
        return -1;
    }

    switch (packet.nMsgId)
    {
        case E_CS_HEARTBEAT_REQ:
        {
            iRetCode = OnHeartBeatReq(packet, pSession, req);
            break;
        }
        case E_CS_BATTLESVR_RTT_REQ:
        {
            iRetCode = OnRTTSetClockReq(packet, pSession, req);
            break;
        }
        case E_CS_MAPSVR_LOGIN_REQ:
        {
            iRetCode = OnLoginReq(packet, pSession, req);
            break;
        }
        default:
        {
            LOG_ERR(0, -1, "client msg:({}) not handle", packet.ToString());
            break;
        }
    }
    return 0;
}

int NFCityLoginModule::OnHeartBeatReq(NFDataPackage& packet, NFCitySession* pSession, const proto_ff::Proto_CSReq& req)
{
    CHECK_NULL(0, pSession);

    pSession->SetLastActiveTime(NF_ADJUST_TIMENOW());

    proto_ff::Proto_CSRsp rsp;
    proto_ff::Proto_RoleTimeValue* timevalue = rsp.mutable_heart_beat()->mutable_time_prop();
    if (req.has_heart_beat())
    {
        timevalue->set_value(req.heart_beat().reserve());
    }
    else
    {
        timevalue->set_value(0);
    }
    timevalue->set_next_add_value_time(NF_ADJUST_TIMENOW());
    if (req.has_timestamp())
    {
        rsp.set_timestamp(req.timestamp());
    }

    NFCityPacketSendUtil::SendToClient(pSession, E_CS_HEARTBEAT_RSP, &rsp);
    return 0;
}

int NFCityLoginModule::OnRTTSetClockReq(NFDataPackage& packet, NFCitySession* pSession, const proto_ff::Proto_CSReq& req)
{
    int iRetCode = 0;

    const proto_ff::Proto_CSRTTSetClockReq& rtt_set_clock_req = req.rtt_set_clock_req();
    NFCityCheckTimer::SendClientRttSetClock(pSession, rtt_set_clock_req.seq());

    return iRetCode;
}

int NFCityLoginModule::OnLoginReq(NFDataPackage& packet, NFCitySession* pSession, const proto_ff::Proto_CSReq& req)
{
    const proto_ff::Proto_CSMapSvrLoginReq& oLoginReq = req.mapsvr_login_req();
    uint64_t ullRoleID = oLoginReq.role_id();

    proto_ff::Proto_CSRsp oCSRsp;
    proto_ff::Proto_CSMapSvrLoginRsp* pLoginRsp = oCSRsp.mutable_mapsvr_login_rsp();

    pLoginRsp->set_role_id(ullRoleID);
    pLoginRsp->set_server_time(NF_ADJUST_TIMENOW());

    NFCityPlayer* pPlayer = NFCityPlayerUtil::GetPlayerByRoleID(ullRoleID);
    if (!pPlayer)
    {
        pLoginRsp->set_obj_id(0);
        return NFCityPacketSendUtil::SendToClient(pSession, E_CS_MAPSVR_LOGIN_RSP, &oCSRsp);
    }

    NFCitySession* pOldSession = pPlayer->GetClientSession();
    if (pOldSession && (pOldSession != pSession))
    {
        pOldSession->DisConnect(SESSION_DISCONN_FROM_SERVER, proto_ff::ERR_CODE_ROLE_KICKOFF_HEARTBEAT_TIMEOUT);
    }

    pSession->BindPlayer(pPlayer);
    pPlayer->BindClientSession(pSession);
    pPlayer->SetPlayerStatus(CACHE_STATUS_ONLINE);

    pLoginRsp->set_obj_id(pPlayer->GetGlobalId());

    return NFCityPacketSendUtil::SendToClient(pPlayer, E_CS_MAPSVR_LOGIN_RSP, &oCSRsp);
}
